package com.xiannimei.util;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DateUtil{
	private static final Logger log = LoggerFactory.getLogger(DateUtil.class);

	private final static ConcurrentHashMap<String, SimpleDateFormat> formatCache = new ConcurrentHashMap<String, SimpleDateFormat>(16);

	private final static String localeToCacheKey(Locale locale){
		StringBuilder sb = new StringBuilder(32);
		sb.append("[");
		if (locale != null) {
			sb.append(locale.getLanguage()).append(":").append(locale.getCountry()).append(":").append(locale.getVariant());
		}
		sb.append("]");
		return sb.toString();
	}

	private final static SimpleDateFormat getFormatFromCache(String pattern, Locale locale){
		String key = pattern + localeToCacheKey(locale);
		SimpleDateFormat res = formatCache.get(key);
		if (res == null) {
			res = new SimpleDateFormat(pattern, locale);
			SimpleDateFormat resInCache = formatCache.putIfAbsent(key, res);
			if (resInCache != null) {
				res = resInCache;
			}
			return res;
		}
		return res;
	}

	/**
	 * format 日期类型 格式化成字符串类型
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String format(Date date, String pattern){
		return format(date, pattern, Locale.getDefault());
	}

	/**
	 * format 日期类型 格式化成字符串类型
	 * 
	 * @param date
	 * @param pattern
	 * @param locale
	 * @return
	 */
	public static String format(Date date, String pattern, Locale locale){
		if (StringUtils.isNotBlank(pattern)) {
			String format = getFormatFromCache(pattern, locale).format(date);
			return format;
		}
		throw new IllegalArgumentException("param pattern can not be null");
	}

	/**
	 * parse 字符串类型转成日期类型
	 * 
	 * @param dateString
	 * @param pattern
	 * @return
	 */
	public static Date parse(String dateString, String pattern){
		return parse(dateString, pattern, Locale.getDefault());
	}

	/**
	 * 字符串类型转成日期类型
	 * 
	 * @param dateString
	 * @param pattern
	 * @param locale
	 * @return
	 */
	public static Date parse(String dateString, String pattern, Locale locale){
		if (StringUtils.isNotBlank(dateString)) {
			ParsePosition parsePosition = new ParsePosition(0);
			Date date = getFormatFromCache(pattern, locale).parse(dateString, parsePosition);
			Object[] objects = { dateString, pattern, parsePosition };
			log.debug("dateString:[{}], pattern:[{}], parsePosition:[{}]", objects);
			return date;
		}
		throw new IllegalArgumentException("param dateString can not be null");
	}

	/**
	 * 得到指定时间在指定天数之后的时间(传入负整数表示之前)
	 */
	public static Date calDaysAfter(Date date, int afterDay){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, afterDay);
		return calendar.getTime();
	}

	/**
	 * 得到指定时间在指定小时数之后的时间(传入负整数表示之前)
	 */
	public static Date calHoursAfter(Date date, int afterHour){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.HOUR, afterHour);
		return calendar.getTime();
	}

	/**
	 * 得到指定时间在指定分钟数之后的时间(传入负整数表示之前)
	 */
	public static Date calMinutesAfter(Date date, int afterMinute){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MINUTE, afterMinute);
		return calendar.getTime();
	}

	/**
	 * 得到指定时间在指定秒数之后的时间(传入负整数表示之前)
	 */
	public static Date calSecondsAfter(Date date, int afterSecond){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, afterSecond);
		return calendar.getTime();
	}

	/**
	 * 获得传入参数当天 00:00:00 的Date对象
	 */
	public static Date getDayStart(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获得传入参数当天 23:59:59 的Date对象
	 */
	public static Date getDayEnd(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		return calendar.getTime();
	}
}
